package com.atXiao.Queue;

/**
 * 数组模拟环形队列
 */
public class CircleQueueDemo {

    public static void main(String[] args) {
        CircleQueue circleQueue = new CircleQueue(4);
        circleQueue.addData(1);
        System.out.println("----打印队列----");
        circleQueue.printCircleQueueData();
        System.out.println("----打印队列----");
        circleQueue.addData(2);
        System.out.println("----打印队列----");
        circleQueue.printCircleQueueData();
        System.out.println("----打印队列----");
        circleQueue.addData(3);
        System.out.println("----打印队列----");
        circleQueue.printCircleQueueData();
        System.out.println("----打印队列----");
        circleQueue.addData(4);
        System.out.println("----打印队列----");
        circleQueue.printCircleQueueData();
        System.out.println("----打印队列----");



    }






}

class CircleQueue {

    //最大值
    private int maxSize;


    //队列头指针(指向队列的头部第一个元素)
    private int front;

    //队列尾部指针(指向队列的尾部的倒数第二个元素，空余最后的一个位置，该位置用作约定的位置。并且该位置是动态变化的)
    private int rear;

    //存放数据的队列
    private int[] array;


    //初始化构造器
    public CircleQueue(int initSize) {
        maxSize = initSize;
        array = new int[initSize];
    }

    /**
     * 判断队列的元素是否满了
     * 分析: front在首部，rear在倒数第二，且长度为maxSize-1
     *
     * @return
     */
    public boolean isFull() {
        return (rear + 1 - front) % maxSize == front;
    }


    /**
     * 判断队列是否为空的
     *
     * @return
     */
    public boolean isEmpty() {
        return front == rear;
    }


    /**
     * 队列中添加元素
     */
    public void addData(int data) {
        //TODO 1.判断队列是否已经满了
        if (isFull()) {
            System.out.println("当前队列已经满了~~~");
        }
        //TODO 2.未满的状态下进行添加元素   怎么添加?
        //赋值
        array[rear] = data;
        //rear后移，且考虑取模，因为当前的队列是环形的，存在溢出的风险
        rear = (rear + 1) % maxSize;

    }


    /**
     * 元素出队列
     */

    public int popData() {
        int res = 0;
        //TODO 1.判断当前队列是否为空
        if (isEmpty()) {
            System.out.println("当前队列为空，无法获取队首的元素");
        } else {
            res = array[front];
            front = (front + 1) % maxSize;
            return res;
        }
        return res;
    }

    /**
     * 打印当前环形队列的元素列表
     */

    public void printCircleQueueData() {
        for (int i = front; i < front + getRealSize(); i++) {
            System.out.println(array[i%maxSize]);
        }
    }


    /**
     * 获取当前队列的有效元素个数
     */
    public int getRealSize() {
        return (rear + maxSize - front) % maxSize;
    }


}







